Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 13.01.2017, 14:36
Профессор
Отправить личное сообщение для smart-create Посмотреть профиль Найти все сообщения от smart-create
 
Регистрация: 25.10.2016
Сообщений: 157

Передача файла на сервер ajax
Добрый день! Пытаюсь написать обработчик формы через которую пользователь оставляет отзыв и может прикрепить фотографию.

Все отлично работает кроме загрузки фотографии, она попросту не загружается, а почему я не понимаю, все делаю правильно вроде бы, а она не грузиться хоть ты убей, при этом консоль нечего не говорит, успешно возвращается success, и network в консоли говорит что все "ок, информация передана".

Может быть причина в php, может в клиенте, я уже не знаю, прошу взглянуть на мои скрипты, может вы поймете где у меня ошибка:

Разметка формы:
<form id="contact-form" enctype="multipart/form-data" method="post" action="comments/add_comments">
	<input type="name" placeholder="Ваше имя" name="comments_name">
	<input type="text" placeholder="Город/поселок" name="comments_city">
	<input type="email" placeholder="Ваш e-mail адрес" name="comments_email">
	<input type="tel" placeholder="Ваш номер телефона" name="comments_phone">
	<textarea placeholder="Пожалуйста напишите Ваш отзыв, здесь" name="comments_message" rows="3"></textarea><br>
	<br>
	<label class="control-label">Вы можете поделиться фотографиями с отдыха:</label><br>
	<br>
	<input type="file" name="img">
	<br>
	<button type="submit" class="button--8">ОСТАВИТЬ ОТЗЫВ</button>
</form>


JS обработчик формы:
$("form#contact-form").submit(function(e){
	e.preventDefault();
	var f = this,
		   data = $(f.elements).slice(0, -1),
        s = $(f.elements).last(),
        e = s.end().slice(0, -2).removeClass('input-error').filter(function() {
            return !$.trim(this.value)
        });
    if(e.length) e.addClass('input-error');
	else {
		s.prop('disabled', 1);
        s.end().not(s);
		$.ajax({
			url: f.action,
			type: 'POST',
			data: data,
			dataType: 'json',
			success: function(data) {
				thx('open');
				create_comments(data);
				f.reset();
				s.prop('disabled', 0);
				e.removeClass('input-error');
				$('body').animate(
					{
						scrollTop:$('.row.comment:first').offset().top - $('.navbar').outerHeight()
					},
					500
				);
			}
		});
	}
});


Обработчик на сервере:
//КОНТРОЛЛЕР
function add_comments() {
	$config['upload_path'] = './photo/';
	$config['allowed_types'] = 'gif|jpg|png|jpeg';
	$config['max_size']	= '3000';
	$config['encrypt_name']	= TRUE;
	$config['remove_spaces'] = TRUE;
	$this->load->library('upload', $config);
	$this->upload->do_upload();
			
	$image_data = $this->upload->data();
			
	$comments['name']  = $_POST['comments_name'];
	$comments['city'] = $_POST['comments_city'];
	$comments['email'] = $_POST['comments_email'];
	$comments['phone'] = $_POST['comments_phone'];
	$comments['comment'] = $_POST['comments_message'];
	$comments['img'] = $image_data['file_name'];
			
	$comment_id = $this->main_model->new_comments($comments);
			
	$comment = array();
	if ($comment_id)
	{
		$comment = $this->main_model->get_comments_limit(0,1);
	}
			
	echo json_encode($comment);
}
// МОДЕЛЬ
function new_comments($comments){
	$array = array(
		'date' => date("Y-m-d H:i:s", time()),
		'name' => $comments['name'],
		'city' => $comments['city'],
		'email' => $comments['email'],
		'phone' => $comments['phone'],
		'comment' => $comments['comment'],
		'img' => $comments['img']
	);
	$this->db->insert('comments', $array); 
	return $this->db->insert_id();
}


Заранее благодарен за любую помощь

P.S. Серверная часть написана на php-фреймворке Codignaiter
Ответить с цитированием
  #2 (permalink)  
Старый 13.01.2017, 14:48
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

В показанном коде ничего нет о самой загрузке файлов, ищите здесь

$this->load->library('upload', $config);
$this->upload->do_upload();
etc ...
Ответить с цитированием
  #3 (permalink)  
Старый 13.01.2017, 14:57
Профессор
Отправить личное сообщение для smart-create Посмотреть профиль Найти все сообщения от smart-create
 
Регистрация: 25.10.2016
Сообщений: 157

laimas, прошу прошения но это не совсем так, если Вас не затруднит взгляните пожалуйста на документацию Codignaiter:
http://code-igniter.ru/user_guide/li...uploading.html
Ответить с цитированием
  #4 (permalink)  
Старый 13.01.2017, 15:02
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Сообщение от smart-create
это не совсем так
Даже так? Ну-ну, а ничего, что информацию о файлах загруженных нужно искать в массиве $_FILES, чего в вашем коде нет?
Ищите там где указано, загрузкой у вас занимается класс указанный. Вот и разбираться начинайте с него.
Ответить с цитированием
  #5 (permalink)  
Старый 13.01.2017, 16:06
Профессор
Отправить личное сообщение для smart-create Посмотреть профиль Найти все сообщения от smart-create
 
Регистрация: 25.10.2016
Сообщений: 157

Сообщение от laimas Посмотреть сообщение
Даже так? Ну-ну, а ничего, что информацию о файлах загруженных нужно искать в массиве $_FILES, чего в вашем коде нет?
Ищите там где указано, загрузкой у вас занимается класс указанный. Вот и разбираться начинайте с него.
Я понимаю о чем вы говорите, но у Codignaiter есть свой подход к загрузке фалов, весь замес происходит тут:
function add_comments() {
	$config['upload_path'] = './photo/'; // задаем путь для загрузки
	$config['allowed_types'] = 'gif|jpg|png|jpeg'; // задаем допустимые типы загружаемых файлов
	$config['max_size']	= '3000'; // задаем максимальный допустимый размер загруженного файла
	$config['encrypt_name']	= TRUE; // переименовываем загружаемый файл в набор символов типа: "a86e4526e164492ebe858ed9a87522d8.png"
	$config['remove_spaces'] = TRUE; // удаляем пробелы в названии файла и меняем их на "_"
	$this->load->library('upload', $config); // загружаем массив со всеми указанными параметрами в библиотеку 'upload'
	$this->upload->do_upload(); // вызываем функцию из библиотеки 'upload' которая и загружает изображения со всеми указанными выше параметрами
			
	$image_data = $this->upload->data(); // получаем имя загружаемого изображения
			
	$comments['name']  = $_POST['comments_name'];
	$comments['city'] = $_POST['comments_city'];
	$comments['email'] = $_POST['comments_email'];
	$comments['phone'] = $_POST['comments_phone'];
	$comments['comment'] = $_POST['comments_message'];
	$comments['img'] = $image_data['file_name'];
			
	$comment_id = $this->main_model->new_comments($comments);
			
	$comment = array();
	if ($comment_id)
	{
		$comment = $this->main_model->get_comments_limit(0,1);
	}
			
	echo json_encode($comment);
}


И что самое главное, он 100% работает. Это можно увидеть если не навешивать на форму мой jq-обработчик:
$("form#contact-form").submit(function(e){
	e.preventDefault();
	var f = this,
		   data = $(f.elements).slice(0, -1),
        s = $(f.elements).last(),
        e = s.end().slice(0, -2).removeClass('input-error').filter(function() {
            return !$.trim(this.value)
        });
    if(e.length) e.addClass('input-error');
	else {
		s.prop('disabled', 1);
        s.end().not(s);
		$.ajax({
			url: f.action,
			type: 'POST',
			data: data,
			dataType: 'json',
			success: function(data) {
				thx('open');
				create_comments(data);
				f.reset();
				s.prop('disabled', 0);
				e.removeClass('input-error');
				$('body').animate(
					{
						scrollTop:$('.row.comment:first').offset().top - $('.navbar').outerHeight()
					},
					500
				);
			}
		});
	}
});


Вы можете сами в этом убедиться перейдя по ссылке http://villabavaria.net/comments

Самый последний комментарий там, оставлен мной, только что, можно увидеть что картинка там есть. Если есть желание оставьте совой отзыв и убедитесь.

Одним словом все работает как нужно, до тех пор пока я не навешиваю обработчик с аяксом на форму. Если навесить его, то картинка перестает загружаться
Ответить с цитированием
  #6 (permalink)  
Старый 13.01.2017, 16:21
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Мне не нужно никуда переходить я и без этого знаю, что загрузкой занимается не код показанный, а класс указанный. Читайте мануал о загрузке файлов на сервер.

На клиенте же, чтобы передать файлы методом $.ajax jQuey, этому методу обязательно нужно указать параметры: contentType: false и processData: false, в противном случае форма будет отправлена не как multipart/form-data, что требуется при отправке файлов, а как текст application/x-www-form-urlencoded.

Если бы заглянули куда вам говорилось или бы открыли отладчик браузера, ясна бы была причина, вы же пытаетесь икать ее там, где ее не увидеть.

PS. Сразу добавлю, что следующая причина "все равно ..." кроется здесь: data: data.

Последний раз редактировалось laimas, 13.01.2017 в 16:46.
Ответить с цитированием
  #7 (permalink)  
Старый 13.01.2017, 16:58
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Сюда, почитайте и без всяких контроллеров, простым кодом, отдельным файлом, на локальном сервере потренируйтесь пока не уясните как работает это. А уж потом во что угодно... Странно, что есть CMS, и если есть готовое для асинхронной загрузки, использовать нечто свое не работающее.
Ответить с цитированием
  #8 (permalink)  
Старый 13.01.2017, 18:20
Профессор
Отправить личное сообщение для smart-create Посмотреть профиль Найти все сообщения от smart-create
 
Регистрация: 25.10.2016
Сообщений: 157

Сообщение от laimas Посмотреть сообщение
Странно, что есть CMS, и если есть готовое для асинхронной загрузки, использовать нечто свое не работающее.
laimas, хотите смейтесь надо мной, я готов уже признать что я тупой. Не понимаю я логики, а готовое не использую потому что хочу сам разобраться, я уже нашел много вариантов сделанных с помощью различных плагинов, но хотелось бы понять самому, что пока не получается, воспользовавшись информацией по ссылке которую Вы мне прислали, я сделал у себя вот так:
$("form#contact-form").submit(function(e){
	e.preventDefault();
	var f = this,
	      data = new FormData(this),
        s = $(f.elements).last(),
        e = s.end().slice(0, -2).removeClass('input-error').filter(function() {
            return !$.trim(this.value)
        });
    if(e.length) e.addClass('input-error');
	else {
		s.prop('disabled', 1);
        s.end().not(s);
		$.ajax({
			url: f.action,
			type: 'POST',
			data: data,
			contentType: false,
			processData: false,
			cache: false,
			dataType: 'json',
			success: function(data) {
				thx('open');
				create_comments(data);
				f.reset();
				s.prop('disabled', 0);
				e.removeClass('input-error');
				$('body').animate(
					{
						scrollTop:$('.row.comment:first').offset().top - $('.navbar').outerHeight()
					},
					500
				);
			}
		});
	}
});


Сейчас сервер не дает не каких ошибок, все "ОК", данные сервером принимаются в формате:

------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_name"

йцу
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_city"

zxczxc
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_email"

qwe@qwe.qwe
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_phone"

123123
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="comments_message"

йцуйцуйцу
------WebKitFormBoundarySddb9HE5iPuiUvar
Content-Disposition: form-data; name="userfile"; filename="ico_1_(1).png"
Content-Type: image/png


------WebKitFormBoundarySddb9HE5iPuiUvar--

Но что-то все равно не так..., загрузка не происходит, комментарий тоже не сохраняется, да и success попросту не отрабатывается.

Одним словом я снова в тупике, не знаю в какую сторону двигаться, отладчик нечего не говорит, для него все "ОК"

Последний раз редактировалось smart-create, 13.01.2017 в 18:43.
Ответить с цитированием
  #9 (permalink)  
Старый 13.01.2017, 19:00
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Судя по Content-Disposition: form-data; name="userfile"; filename="ico_1_(1).png"
Content-Type: image/png (далее должны следовать бинарные данные файла) файл передается. Далее причины уже на сервере искать надо.

Примеры по ссылке работают? Массив $_FILES показывает информацию о загрузке? Это же самое можно проверить и в классе производящем загрузку.
Ответить с цитированием
  #10 (permalink)  
Старый 13.01.2017, 19:17
Профессор
Отправить личное сообщение для smart-create Посмотреть профиль Найти все сообщения от smart-create
 
Регистрация: 25.10.2016
Сообщений: 157

laimas, нужно было просто протереть глаза..., нашел синтаксическую ошибку в php. Как всегда, крайне признателен Вам за помощь
Чувствую еще годик такого общения и я благодаря Вам диссертацию напишу. Спасибо!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Отправка запроса в виде XML файла на сервер и получение ответа sojar Общие вопросы Javascript 0 23.08.2015 12:34
AJAX Не ждет сервер, пока последний отправляет письмо 161login AJAX и COMET 2 16.11.2014 06:06
Передача HTML кода на сервер через Ajax KomaLex AJAX и COMET 2 06.12.2012 15:28
Проблема с загрузкой файла на сервер shkarbatov Серверные языки и технологии 8 13.08.2011 01:27
передача JSON на сервер mikeles AJAX и COMET 0 04.03.2011 11:28